package com.wn.wanflow.note

/**
 * @Author: wn
 * @Date: 2024/7/3 16:12
 * @Description: 笔记
 */
/*
 1 enum
跟 class 类似 有构造函数时  其成员变量 可以根据构造函数实例化
enum class ERROR(val code: Int, val errMsg: String) {
  UNAUTHORIZED(401, "当前请求需要用户验证")
}
可以有 fun  可以 继承父类 实现接口  重写其方法

2 sealed -- 密封类
 sealed class Result
 data class Success(val data: String) : Result()
 object Loading : Result()
 有限子类集合 -- 只能在密封类的同一文件中定义其所有子类,这样编译器就能够在检查时知道所有可能的子类
 模式匹配  --  when 表达式  无需 else 分支  以为密封 编译器可以知道
 封闭性  密封类是封闭的，不能在其他文件中添加新的子类 只能同一文件

3 构造函数
执行顺序 1 主构造函数 -- 2 代码快成员 -- 3 init{ } -- 4 次构造函数
class Student (val name:String) : Person(){
 constructor() : this("")
}
constructor 为次构造函数  必须 继承 主构造函数

没有主构造函数 所以 继承 父类时 无需 ()
次构造函数也无法继承 主构造函数 因为没有主构造函数 所以只能继承 父类的构造函数 -- super()
class Student  : Person{
 constructor() : super()
}

4 @file:JvmName("Test")  必须写在文件首行之上
Test.kt 编译后生成 TestKt -- java 端 调用  TestKt.test()
JvmName 编译后生成 Test   -- java 端 调用  Test.test()

@JvmField  -- 消除kotlin的默认私有访问权限，使Java端可以以public调用
 var name = "Allen"  -- private String name = "Allen"  new Person().getName() ,伴生可直接
 @JvmField
 var name = "Allen"  -- public String name = "Allen"   new Person().name

@JvmOverloads
fun method(name : String, age : Int = 18){
    println("我的名字是: ${name},我今年 $age 岁了")
}
kotlin 端 只传 name一个参数即可 , java 有缺省值的 情况下 也要传递 全参
加上 @JvmOverloads  强制  重载  就可以传递 任意参数  1 or 2

@JvmStatic
class Person_Test{
    companion object{
        fun showMethod(name : String){
            println("${name} 今年18岁了")
        }
    }
}

KT     Person_Test.showMethod("Allen")
java   Person_Test.Companion.showMethod("Allen");
companion object 反编译后其实又生成了一个Companion类 ,showMethod被封装在了里面 所以  Person_Test.Companion.showMethod
@JvmStatic -- 类中 封装了一个static 的showMethod ,然后也是调用了Companion里面的showMethod方法  -- Person_Test.showMethod("Allen")

总结：
1.@JvmName：便于去修改kt文件背后生成的类名，必须写在包名上面
2.@JvmField： 消除kotlin的默认私有访问权限,无需  get
3.@JvmOverloads: 生成重载方法，便于Java在调用有 默认值 参数的函数的时候 可以仅传入无默认值的那些参数
4.@JvmStatic：使Java在调用派生类Companion Object的函数使能够像调用static方法一样，直接xx类 . xx方法

5 AROuter -- 路径 至少两级  /X/X
 1 页面跳转
 ARouter.getInstance().build("/app/MainActivity").navigation()
 2 传参
ARouter.getInstance().build(路径)
        .withChar("CharKey", 'a')
        .withShort("ShortKey", 1)
        .withInt("IntKey", 11)
        .withLong("LongKey", 12l)
        .withFloat("FloatKey", 1.1f)
        .withDouble("DoubleKey", 1.1d)
        .withBoolean("BooleanKey", true)
        .withString("StringKey", "value")
         // 序列化对象
         .withSerializable("SerializableKey", new TestObj())
        .withParcelable("ParcelableKey", new TestObj())
        .navigation();

  // 用Autowired注解 获取参数
  @Autowired(name = "IntKey")
  int i;
  @Autowired(name = "StringKey")
  String str;

3 不同模块之间 方法调用
A B 都依赖 common
common 中
interface IAService : IProvider
interface IBService : IProvider

A B 模块中 中定义 接口 实例
@Route(path = "/X/X")
class AService : IAService
class BService : IBService

common 中
定义 Object提供实例
object AServiceProvider {
  @Autowired(name = "/X/X")
  lateinit var aService: IAService

A B 模块便可以 通过 common中 的  Provider 获取对应 实例  调用 实例方法

6    自定义 Navigator 实现切换 Tab 的时候 Fragment 生命周期不会重新执行了
     A->B
     A: onAttach -> onCreateView -> onViewCreated -> onStart -> onResume
     B: A onPause -> onStop ,并没有走onDestroy
     A: onCreateView -> onViewCreated -> onStart -> onResume
     重走生命周期不仅意味着要消耗额外的资源对 Fragment 进行重新渲染，也降低了用户体验
     解决方案 自定义 wnFragment :FragmentNavigator -> 把replace方法替换为hidden和add方法即可
    1 app:navGraph="@navigation/mobile_navigation"  移除 , 代码中动态添加
    2 重写 WindowNavHostFragment : NavHostFragment(),替换 android:name="androidx.navigation.fragment.NavHostFragment"
    3 自定义 wnFragment :FragmentNavigator -> 把replace方法替换为 hidden 和 add 方法即可
    4 navigation-xml-> navGraph 中 替换自定义 -> wnFragment
    5 MainActivity 代码中 addNavigator(wnFragment) ,SetGraph(R.navigation.mobile_navigation)

7























 */